home *** CD-ROM | disk | FTP | other *** search
/ Hyper Stacks 1994 May / Hyper Stacks (Pacific HiTech)(1994)[Mac].iso / Organization / TEX ƒ / openCloseTEXFiles 0.5.c < prev    next >
Text File  |  1988-09-04  |  7KB  |  310 lines

  1. /* new HyperCard XFCN to open/close index, context, and text files
  2.  * copyright 1988 Mark ^Zimmermann - 880831-0904
  3.  *
  4.  * Call this XFCN as 'openCloseTEXfiles([optional list of numbers here])'.
  5.  *
  6.  * If the XFCN is called with no arguments, it puts up the standard files
  7.  * dialog box and gives back in return the file refNums for the text
  8.  * (document/dataspace) file, *.k, and *.p files, on one line, in
  9.  * that order, separated by spaces.  Note that the *.k and *.p files
  10.  * must be in the same folder as the master dataspace file; an earlier
  11.  * version of this XFCN tried to allow them to be elsewhere (or to
  12.  * have different names), but it was too complex and didn't seem to be
  13.  * appreciated by the users!
  14.  *
  15.  * If the XFCN is passed any numerical parameters, it attempts to
  16.  * close them (assuming they are file refNums) and doesn't try to
  17.  * open anything....
  18.  *
  19.  * If an error while opening a file seems to occur, the XFCN attempts
  20.  * to close all files that have already been opened, and returns with
  21.  * an error msg instead of the three file refNums.  No error checking
  22.  * is done on closing files, since there's not much that one could
  23.  * do about such an error in any case....
  24.  *
  25.  */
  26.  
  27.  
  28. #include <MacTypes.h>
  29. #include <FileMgr.h>
  30. #include <StdFilePkg.h>
  31. #include <HyperXCmd.h>
  32.  
  33. #define NULL  0
  34.  
  35. /* define these to allow use of global variables in my XFCNs; a
  36.  * Lightspeed C necessity, apparently...
  37.  */
  38.  
  39. #define SetUpA4()        asm  {    move.l a4,-(sp)        \
  40.                                 move.l a0,a4    }
  41.  
  42. #define RestoreA4()        asm  {    move.l (sp)+,a4    }
  43.  
  44.  
  45. pascal void main (XCmdBlockPtr paramPtr);
  46. int zGetFile (Str255 *fileNamePtr, int *volRefNumPtr, long fileType);
  47. void returnErrorMsg (XCmdBlockPtr paramPtr, char *msg);
  48. long atol (char *s);
  49. void ltoaR (char *ansp, long n, int maxDigits);
  50. int strlen (char *s);
  51. char *strcpy (char *s1, char *s2);
  52.  
  53.  
  54. pascal void main (paramPtr)
  55.   XCmdBlockPtr paramPtr;
  56.   {
  57.     Str255 fileName;
  58.     int refNum, volRefNum, textFileRefNum, keyFileRefNum, ptrFileRefNum,
  59.         i, errNum;
  60.     Handle answer;
  61.  
  62.     SetUpA4();
  63.     if (paramPtr->paramCount != 0)
  64.       {
  65.         for (i = 0; i < paramPtr->paramCount; ++i)
  66.           {
  67.             refNum = atol (*(paramPtr->params[i]));
  68.             FSClose (refNum);
  69.           }
  70.         RestoreA4();
  71.         return;
  72.       }
  73.  
  74.     if (! zGetFile (&fileName, &volRefNum, 'TEXT'))
  75.       {
  76.         RestoreA4();
  77.         return;
  78.       }
  79.  
  80.     errNum = FSOpen (&fileName, volRefNum, &textFileRefNum);
  81.     if (errNum != noErr && errNum != opWrErr)
  82.       {
  83.          returnErrorMsg (paramPtr,
  84.               "{Sorry, error in opening text file!}");
  85.           RestoreA4();
  86.           return;
  87.       }
  88.  
  89.     *(fileName + *fileName + 1) = '.';
  90.     *(fileName + *fileName + 2) = 'k';
  91.     *fileName += 2;
  92.     errNum = FSOpen (&fileName, volRefNum, &keyFileRefNum);
  93.     if (errNum != noErr && errNum != opWrErr)
  94.       {
  95.         FSClose (textFileRefNum);
  96.           returnErrorMsg (paramPtr,
  97.                     "{Sorry, error in opening index key (*.k) file!}");
  98.           RestoreA4();
  99.           return;
  100.       }
  101.  
  102.     *(fileName + *fileName) = 'p';
  103.     errNum = FSOpen (&fileName, volRefNum, &ptrFileRefNum);
  104.     if (errNum != noErr && errNum != opWrErr)
  105.       {
  106.         FSClose (textFileRefNum);
  107.         FSClose (keyFileRefNum);
  108.           returnErrorMsg (paramPtr,
  109.                     "{Sorry, error in opening index ptr (*.p) file!}");
  110.           RestoreA4();
  111.           return;
  112.       }
  113.  
  114.     if ((answer = NewHandle (20)) == NULL)
  115.       {
  116.         FSClose (textFileRefNum);
  117.         FSClose (keyFileRefNum);
  118.         FSClose (ptrFileRefNum);
  119.           returnErrorMsg (paramPtr,
  120.             "{Sorry, bad out of memory error in XFCN openTEXfiles call!}");
  121.           RestoreA4();
  122.           return;
  123.       }
  124.  
  125.     ltoaR (*answer, textFileRefNum, 6);
  126.     ltoaR (*answer + 6, keyFileRefNum, 6);
  127.     ltoaR (*answer + 12, ptrFileRefNum, 6);
  128.     *(*answer + 18) = '\0';
  129.  
  130.     paramPtr->returnValue = answer;
  131.     RestoreA4();
  132.     return;
  133.   }
  134.  
  135.  
  136. /* this routine, adapted from the Lightspeed C 'MiniEdit' example, does
  137.  * the standard files dialog routine to get the name of the text file
  138.  * of the dataspace; other file names are gotten from that by putting
  139.  * a '.k' or a '.p' at the end.  This routine returns 1 if all is well,
  140.  * or 0 if the user cancels out...
  141.  */
  142.  
  143. int zGetFile (fileNamePtr, volRefNumPtr, fileType)
  144.   Str255 *fileNamePtr;
  145.   int *volRefNumPtr;
  146.   long fileType;
  147.   {
  148.     SFTypeList myFileTypes;
  149.     Point SFGwhere;
  150.     SFReply myReply;
  151.     register int i;
  152.  
  153.     SFGwhere.v = 90;
  154.     SFGwhere.h = 82;
  155.     myFileTypes[0] = fileType;
  156.     
  157.     SFGetFile (SFGwhere, "\p", 0L, 1, myFileTypes, 0L, &myReply);
  158.     
  159.     if (myReply.good)
  160.       {
  161.         for (i = *myReply.fName; i >= 0; --i)
  162.             (*fileNamePtr)[i] = myReply.fName[i];
  163.         *volRefNumPtr = myReply.vRefNum;
  164.         return (1);
  165.       }
  166.     else
  167.         return (0);
  168.   }
  169.  
  170.  
  171. /* function to set the return value of the XFCN to a chosen error msg;
  172.  * if there isn't enough free memory to give us a Handle to the msg,
  173.  * beep a bunch and then return!
  174.  */
  175.  
  176. void returnErrorMsg (paramPtr, msg)
  177.   XCmdBlockPtr paramPtr;
  178.   char *msg;
  179.   {
  180.     Handle answer;
  181.     int msgLength;
  182.     
  183.     SysBeep (10);
  184.     msgLength = strlen (msg);
  185.     if ((answer = NewHandle (1 + msgLength)) == NULL)
  186.       {
  187.         SysBeep (10);
  188.         SysBeep (10);
  189.         SysBeep (10);
  190.         SysBeep (10);
  191.         SysBeep (10);
  192.         return;
  193.       }
  194.  
  195.     strcpy (*answer, msg);
  196.     paramPtr->returnValue = answer;
  197.     return;
  198.   }
  199.  
  200.  
  201. /* function to convert alphanumeric string to a long int, from K&R & LSC
  202.  * library.... simplified to avoid using isspace() & isdigit() ....
  203.  */
  204.  
  205. long atol (s)
  206.   register char *s;
  207.   {
  208.     int signflag = 0;
  209.     register long r = 0;
  210.  
  211.     while (*s == ' ')
  212.         s++;
  213.         
  214.     if (*s == '-')
  215.       {
  216.         signflag = 1;
  217.         s++;
  218.       }
  219.     else if (*s == '+')
  220.          s++;
  221.  
  222.     while (*s >= '0' && *s <= '9') 
  223.         r = r * 10 + (*s++ - '0');
  224.     
  225.     return (signflag ? -r : r);
  226. }
  227.  
  228.  
  229. /* function to convert a number into a string of width maxDigits and
  230.  * store it right-justified, blank-filled on left; based on K&R p. 60
  231.  * example of itoa().
  232.  *
  233.  * Error handling:  put a '>' or '<' in leading place to warn of an
  234.  * overflow (no room for digits on a positive or negative number,
  235.  * respectively), and put a '^' in leading place to warn if no room
  236.  * for '-' sign on negative number...
  237.  */
  238.  
  239. void ltoaR (ansp, n, maxDigits)
  240.   register char *ansp;
  241.   register long n;
  242.   int maxDigits;
  243.   {
  244.     register int i;
  245.     long sign;
  246.     
  247.     i = maxDigits - 1;
  248.     if ((sign = n) < 0)
  249.         n = -n;
  250.     
  251.     do
  252.       {
  253.           ansp[i--] = n % 10 + '0';
  254.       }
  255.     while ((n /= 10) > 0 && i >= 0);
  256.     
  257.     if (i < 0 && n > 0)        /* ran out of room with digits still to go */
  258.       {
  259.         if (sign > 0)
  260.             ansp[0] = '>';            /* positive overflow signal */
  261.         else
  262.             ansp[0] = '<';            /* negative overflow signal */
  263.       }
  264.     else
  265.       {
  266.         if (sign < 0)
  267.             if (i >= 0)
  268.                 ansp[i--] = '-';
  269.             else
  270.                 ansp[0] = '^';        /* no room for '-' sign signal */
  271.         for ( ; i >= 0; --i)
  272.             ansp[i] = ' ';
  273.       }
  274.  
  275.     return;
  276.   }
  277.   
  278.  
  279. /* function to determine the length of a string ... standard thing,
  280.  * adapted from the LSC library, and K&R p.98 ....
  281.  */
  282.  
  283. int strlen (s)
  284.   register char *s;
  285.   {
  286.     char *s0 = s;
  287.  
  288.     while (*s++)
  289.         ;
  290.     return (s - s0 - 1);
  291.   }
  292.  
  293.  
  294. /* function to copy a string from one place to another, in a rather
  295.  * obvious fashion ... adapted from the LSC library, and K&R p.101 ....
  296.  */
  297.  
  298. char *strcpy (s1, s2)
  299.   register char *s1, *s2;
  300.   {
  301.     char *s = s1;
  302.     
  303.     while (*s1++ = *s2++)
  304.         ;
  305.     return (s);
  306.   }
  307.  
  308.  
  309.  
  310.